package com.demo.testvideoview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import java.util.Formatter;
import java.util.Locale;


public class MediaControllerView extends MediaController implements View.OnClickListener {

    private static final String TAG = MediaControllerView.class.getSimpleName();

    private static final int sDefaultTimeout = 5000;

    private Context mContext;


    private RelativeLayout relativeLayout;
    private View rootView;

    private MediaPlayerControl mPlayer;



    private ProgressBar mProgress;
    private TextView mEndTime, mCurrentTime;
    private ImageView ivPause;

    private ImageView ivNext;
    private ImageView ivPrev;
    private ImageView ivFullscreen;


    private StringBuilder mFormatBuilder;
    private Formatter mFormatter;

    private boolean mShowing;
    private boolean mDragging;

    private MediaControllerButton mediaControllerButton;

    public MediaControllerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MediaControllerView(Context context, boolean useFastForward) {
        super(context, useFastForward);

        mContext = context;
        initView();

    }

    public MediaControllerView(Context context) {
        this(context, true);
    }

    private void initView(){
        LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rootView = inflate.inflate(R.layout.layout_videocontroller,null);

        initControllerView();
    }


    private void initControllerView(){

        mProgress = rootView.findViewById(R.id.sb_progress);
        mCurrentTime = rootView.findViewById(R.id.tv_currenttime);
        mEndTime = rootView.findViewById(R.id.tv_endtime);



        ivPause = rootView.findViewById(R.id.iv_pause);
        ivFullscreen = rootView.findViewById(R.id.iv_fullscreen);

        if (mProgress != null) {
            if (mProgress instanceof SeekBar) {
                SeekBar seeker = (SeekBar) mProgress;
                seeker.setOnSeekBarChangeListener(mSeekListener);
            }
            mProgress.setMax(1000);
        }

        if (ivPause != null) {
            ivPause.requestFocus();
            ivPause.setOnClickListener(mPauseListener);
        }

        ivFullscreen.setOnClickListener(this);
        rootView.setOnClickListener(this);

        mFormatBuilder = new StringBuilder();
        mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());

    }

    @Override
    public void setAnchorView(View view) {
        removeAllViews();

        relativeLayout  = (RelativeLayout) view;
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
        );
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);

        relativeLayout.addView(rootView,layoutParams);


    }

    @Override
    public void setMediaPlayer(MediaPlayerControl player) {
        mPlayer = player;
    }

    @Override
    public void show() {
       // super.show();
        show(sDefaultTimeout);
    }


    @Override
    public void onClick(View v) {

        if(mediaControllerButton!=null){
            switch (v.getId()){
                case R.id.iv_fullscreen:
                    mediaControllerButton.fullscreen();
                    break;
            }
        }

    }


    @Override
    public void show(int timeout) {



        if(!mShowing){

            rootView.setVisibility(VISIBLE);

            setProgress();
            mShowing = true;

        }
        updatePausePlay();

        rootView.post(mShowProgress);

        if (timeout != 0) {
            rootView.removeCallbacks(mFadeOut);
            rootView.postDelayed(mFadeOut, timeout);
        }

    }

    @Override
    public void hide() {


        if (mShowing) {
            try {
                removeCallbacks(mShowProgress);
                rootView.setVisibility(GONE);
            } catch (IllegalArgumentException ex) {
                Log.w("MediaController", "already removed");
            }
            mShowing = false;
        }

    }


    private String stringForTime(int timeMs) {
        int totalSeconds = timeMs / 1000;

        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours   = totalSeconds / 3600;

        mFormatBuilder.setLength(0);
        if (hours > 0) {
            return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
        } else {
            return mFormatter.format("%02d:%02d", minutes, seconds).toString();
        }
    }
    private final Runnable mShowProgress = new Runnable() {
        @Override
        public void run() {
            int pos = setProgress();
            if (!mDragging && mShowing && mPlayer.isPlaying()) {
                rootView.postDelayed(mShowProgress, 1000 - (pos % 1000));
            }
        }
    };

    private int setProgress() {
        if (mPlayer == null || mDragging) {
            return 0;
        }
        int position = mPlayer.getCurrentPosition();
        int duration = mPlayer.getDuration();

        Log.e(TAG, "setProgress: position="+position+" duration="+duration );

        if (mProgress != null) {
            if (duration > 0) {
                // use long to avoid overflow
                long pos = 1000L * position / duration;
                mProgress.setProgress( (int) pos);
            }
            int percent = mPlayer.getBufferPercentage();
            mProgress.setSecondaryProgress(percent * 10);
        }

        if (mEndTime != null)
            mEndTime.setText(stringForTime(duration));
        if (mCurrentTime != null)
            mCurrentTime.setText(stringForTime(position));

        return position;
    }




    private void updatePausePlay() {
        if (rootView == null || ivPause == null)
            return;

        if (mPlayer.isPlaying()) {
            ivPause.setImageResource(R.drawable.icon_video_pause);
        } else {
            ivPause.setImageResource(R.drawable.icon_video_play);
        }
    }


    private final Runnable mFadeOut = new Runnable() {
        @Override
        public void run() {
            hide();
        }
    };


    private final SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onStartTrackingTouch(SeekBar bar) {
            show(3600000);

            mDragging = true;


            rootView.removeCallbacks(mShowProgress);
        }

        @Override
        public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
            if (!fromuser) {
                // We're not interested in programmatically generated changes to
                // the progress bar's position.
                return;
            }

            long duration = mPlayer.getDuration();
            long newposition = (duration * progress) / 1000L;
            mPlayer.seekTo( (int) newposition);
            if (mCurrentTime != null)
                mCurrentTime.setText(stringForTime( (int) newposition));
        }

        @Override
        public void onStopTrackingTouch(SeekBar bar) {
            mDragging = false;
            setProgress();
            updatePausePlay();
            show(sDefaultTimeout);

            // Ensure that progress is properly updated in the future,
            // the call to show() does not guarantee this because it is a
            // no-op if we are already showing.
            rootView.post(mShowProgress);
        }
    };




    private final View.OnClickListener mPauseListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            doPauseResume();
            show(sDefaultTimeout);
        }
    };

    private void doPauseResume() {
        if (mPlayer.isPlaying()) {
            mPlayer.pause();
        } else {
            mPlayer.start();
        }
        updatePausePlay();
    }

    public interface MediaControllerButton{
        void next();
        void prev();
        void fullscreen();
    }


    public void setMediaControllerButton(MediaControllerButton mediaControllerButton) {
        this.mediaControllerButton = mediaControllerButton;
    }
}
